<template>
  <Page>
    <!-- 房间列表/创建区域 -->
    <div v-if="!inRoom" class="room-entry">
      <!-- 房间创建/加入表单 -->
      <div class="room-form">
        <el-input
          v-model="userName"
          placeholder="请输入您的昵称（必填）"
          class="form-item"
          :disabled="isConnecting || (isWsConnected && hasSentIdentify)"
          @change="handleUserNameChange"
        ></el-input>

        <el-input
          v-model="roomName"
          placeholder="请输入房间名称（可选）"
          class="form-item"
          :disabled="!canOperate"
        ></el-input>

        <el-input
          v-model="roomId"
          placeholder="请输入4位数字房间号"
          class="form-item"
          :disabled="!canOperate"
          maxlength="4"
          @input="formatRoomId"
        ></el-input>

        <div class="form-buttons">
          <el-button @click="createNewRoom" type="primary" :disabled="!canOperate || !hasSentIdentify">
            <template v-if="isConnecting">处理中...</template>
            <template v-else>随机生成4位数字房间</template>
          </el-button>

          <el-button
            @click="joinExistingRoomManual"
            style="margin-left: 0"
            type="success"
            :disabled="!canOperate || !hasSentIdentify || !isValidRoomId"
          >
            加入指定房间
          </el-button>

          <el-button @click="fetchRoomList" style="margin-left: 0" :disabled="!canOperate">刷新房间列表</el-button>
        </div>

        <div v-if="wsStatus" class="ws-status">
          {{ wsStatus }}
        </div>
      </div>

      <!-- 房间列表 -->
      <div class="room-list">
        <h3>现有房间 ({{ roomList.length }})</h3>
        <div class="room-list-header">
          <div class="room-list-col">房间名称</div>
          <div class="room-list-col">房间号</div>
          <div class="room-list-col">操作</div>
        </div>

        <div v-for="room in roomList" :key="room.id" class="room-list-item">
          <div class="room-list-col">{{ room.name || '未命名房间' }}</div>
          <div class="room-list-col">{{ room.id }}</div>
          <div class="room-list-col">
            <el-button type="text" @click="joinSelectedRoom(room.id)" :disabled="!canOperate || !hasSentIdentify">
              加入
            </el-button>
          </div>
        </div>

        <div v-if="roomList.length === 0 && canOperate && hasSentIdentify" class="empty-room">
          暂无房间，快去创建一个吧～
        </div>
        <div v-if="isWsConnected && !hasSentIdentify" class="empty-room">请输入昵称完成身份验证</div>
        <div v-if="!isWsConnected && !isConnecting" class="empty-room">正在连接服务器...请稍候</div>
      </div>
    </div>

    <!-- 聊天室内部 -->
    <div v-else class="chat-room">
      <div class="room-header">
        <el-button @click="leaveRoom" style="width: 100%" type="danger">离开房间</el-button>
        <div>
          <!-- <span class="room-info">
            房间: {{ currentRoom.name }}({{ currentRoom.id }}) | 在线: {{ onlineUsers.length }}人
          </span>
          <span class="user-info">当前用户: {{ userName }}</span> -->
        </div>
      </div>

      <div class="room-content">
        <!-- 音视频区域 -->
        <div class="video-area">
          <VoiceChat
            ref="voiceChatRef"
            :in-room="inRoom"
            :room-id="currentRoom.id"
            :current-user-id="localUserId"
            :online-users="onlineUsers"
            @sendMediaBuffer="forwardToServer"
            @sendMediaData="forwardToServer"
          />
        </div>

        <!-- 聊天区域 -->
        <div class="message-area">
          <div class="message-list" ref="msgList">
            <div
              v-for="(msg, index) in messages"
              :key="index"
              :class="msg.senderId === localUserId ? 'self-msg' : 'other-msg'"
            >
              <span class="sender">{{ msg.senderName }}:</span>
              <span class="content">{{ msg.content }}</span>
              <span class="time">{{ formatTime(msg.time) }}</span>
            </div>
          </div>
          <div class="message-input">
            <el-input
              v-model="msgContent"
              @keyup.enter="sendChatMsg"
              placeholder="输入消息..."
              :disabled="!inRoom"
            ></el-input>
            <el-button @click="sendChatMsg" :disabled="!msgContent.trim() || !inRoom">发送</el-button>
          </div>
        </div>
      </div>
    </div>
  </Page>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, watch, useTemplateRef } from 'vue'
import Page from '@/components/page/index.vue'
import VoiceChat from './components/VoiceChat.vue'

// 基础状态
const inRoom = ref(false)
const userName = ref('')
const roomName = ref('')
const roomId = ref('')
const roomList = ref([])
const onlineUsers = ref([])
const messages = ref([])
const msgContent = ref('')
const localUserId = ref('')
const currentRoom = ref({ id: '', name: '' })
const voiceChatRef = useTemplateRef('voiceChatRef')

// 路由参数存储
const routeParams = ref({
  name: '',
  roomId: '',
  roomName: ''
})

// WebSocket状态
const ws = ref(null)
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const host = window.location.host
const WS_URL = `${protocol}//${host.replace('5173', '3001')}/websocket/`
const isConnecting = ref(false)
const isWsConnected = ref(false)
const wsStatus = ref('')
const hasSentIdentify = ref(false)

// 计算属性：是否可以进行操作
const canOperate = ref(false)
watch([isWsConnected, isConnecting, hasSentIdentify], () => {
  canOperate.value = isWsConnected.value && !isConnecting.value && hasSentIdentify.value
})

// 房间号验证状态
const isValidRoomId = ref(false)
watch(roomId, val => {
  isValidRoomId.value = /^\d{4}$/.test(val)
})

// 从URL参数中获取数据
const getUrlParams = () => {
  const params = new URLSearchParams(window.location.search)
  return {
    name: params.get('name') || '',
    roomId: params.get('roomId') || '',
    roomName: params.get('roomName') || ''
  }
}

/* -------------------------- WebSocket核心逻辑 -------------------------- */
const initWebSocket = () => {
  if (ws.value || isConnecting.value) return

  isConnecting.value = true
  wsStatus.value = '正在连接服务器...'

  ws.value = new WebSocket(WS_URL)

  ws.value.onopen = () => {
    console.log('WebSocket连接成功')
    isConnecting.value = false
    isWsConnected.value = true
    wsStatus.value = '已连接到服务器'

    // 连接成功后立即处理路由参数
    handleRouteParamsAfterConnect()
  }

  ws.value.onmessage = event => {
    if (event.data instanceof Blob) {
      voiceChatRef.value?.handleMediaData(event.data)
    } else {
      const data = JSON.parse(event.data)
      handleServerMsg(data)
    }
  }

  ws.value.onclose = event => {
    console.log('WebSocket连接关闭', event)
    isWsConnected.value = false
    isConnecting.value = false
    hasSentIdentify.value = false
    wsStatus.value = '连接已关闭，尝试重连...'
    setTimeout(initWebSocket, 3000)
  }

  ws.value.onerror = err => {
    console.error('WebSocket错误:', err)
    wsStatus.value = '连接错误，正在重试...'
    isConnecting.value = false
  }
}

// 连接成功后处理路由参数
const handleRouteParamsAfterConnect = () => {
  // 1. 填充用户昵称
  if (routeParams.value.name && !userName.value) {
    userName.value = routeParams.value.name
    sendIdentify() // 立即发送身份验证
  }

  // 2. 填充房间信息
  if (routeParams.value.roomId && !roomId.value) {
    roomId.value = routeParams.value.roomId
  }
  if (routeParams.value.roomName && !roomName.value) {
    roomName.value = routeParams.value.roomName
  }

  // 3. 获取房间列表（为自动加入做准备）
  if (canOperate.value) {
    fetchRoomList()
  } else {
    // 监听操作权限就绪后获取房间列表
    const unwatch = watch(canOperate, newVal => {
      if (newVal) {
        fetchRoomList()
        unwatch()
      }
    })
  }
}

// 发送用户身份信息到服务器
const sendIdentify = () => {
  if (!ws.value || ws.value.readyState !== WebSocket.OPEN || !userName.value.trim()) return

  sendWsMessage({
    type: 'identify',
    data: {
      userId: localUserId.value,
      userName: userName.value.trim()
    }
  })

  hasSentIdentify.value = true
  wsStatus.value = `已验证身份：${userName.value}`
}

// 处理用户名变化
const handleUserNameChange = () => {
  if (isWsConnected.value && userName.value.trim() && !hasSentIdentify.value) {
    sendIdentify()
  }
}

// 发送消息到服务器
const sendWsMessage = msg => {
  if (!ws.value || ws.value.readyState !== WebSocket.OPEN) {
    console.warn('WebSocket未连接，无法发送消息')
    wsStatus.value = '连接未建立，无法发送消息'
    return
  }

  const message = {
    ...msg,
    timestamp: Date.now(),
    senderId: localUserId.value
  }

  ws.value.send(JSON.stringify(message))
}

/* -------------------------- 房间管理 -------------------------- */
// 创建新房间
const createNewRoom = () => {
  if (!canOperate.value) return

  isConnecting.value = true
  wsStatus.value = '正在创建房间...'

  const newRoomId = Math.floor(1000 + Math.random() * 9000).toString()
  sendWsMessage({
    type: 'createRoom',
    data: {
      roomId: newRoomId,
      roomName: roomName.value || `房间${newRoomId}`,
      userName: userName.value
    }
  })
}

// 加入指定房间（手动输入）
const joinExistingRoomManual = () => {
  if (!canOperate.value || !isValidRoomId.value) return
  doJoinRoom(roomId.value)
}

// 加入选中的房间（从列表）
const joinSelectedRoom = targetRoomId => {
  if (!canOperate.value) return
  roomId.value = targetRoomId
  doJoinRoom(targetRoomId)
}

// 实际执行加入房间
const doJoinRoom = targetRoomId => {
  if (!canOperate.value) return

  isConnecting.value = true
  wsStatus.value = `正在加入房间 ${targetRoomId}...`
  sendWsMessage({
    type: 'joinRoom',
    data: {
      roomId: targetRoomId,
      userName: userName.value
    }
  })
}

// 离开房间
const leaveRoom = () => {
  if (!inRoom.value) return

  sendWsMessage({
    type: 'leaveRoom',
    data: {
      roomId: currentRoom.value.id
    }
  })

  inRoom.value = false
  onlineUsers.value = []
  messages.value = []
  currentRoom.value = { id: '', name: '' }
  voiceChatRef.value?.endMediaCall()
  wsStatus.value = '已离开房间，可以加入其他房间'
}

// 获取房间列表
const fetchRoomList = () => {
  if (!canOperate.value) return

  sendWsMessage({ type: 'getRoomList' })
  wsStatus.value = '正在获取房间列表...'
}

/* -------------------------- 消息处理 -------------------------- */
const handleServerMsg = data => {
  console.log('收到服务器消息:', data)
  isConnecting.value = false

  switch (data.type) {
    case 'connectionSuccess':
      localUserId.value = data.data.userId
      break
    case 'roomCreated':
    case 'roomJoined':
      currentRoom.value = {
        id: data.data.roomId,
        name: data.data.roomName
      }
      inRoom.value = true
      onlineUsers.value = data.data.users
      wsStatus.value =
        data.type === 'roomCreated' ? `房间 ${data.data.roomId} 创建成功` : `已加入房间 ${data.data.roomId}`
      break
    case 'roomList':
      roomList.value = data.data
      wsStatus.value = `房间列表已更新（共${data.data.length}个房间）`
      // 房间列表更新后尝试自动加入房间
      tryAutoJoinRoom()
      break
    case 'userJoined':
      onlineUsers.value.push(data.data.user)
      addSystemMsg(`${data.data.user.name}加入房间`)
      break
    case 'userLeft':
      onlineUsers.value = onlineUsers.value.filter(u => u.id !== data.data.userId)
      addSystemMsg(`${data.data.userName}离开房间`)
      break
    case 'chatMessage':
      messages.value.push(data.data)
      scrollToBottom()
      break
    case 'mediaStatus':
      voiceChatRef.value?.handleStatusData(data)
      break
    case 'error':
      wsStatus.value = `错误: ${data.message}`
      alert(data.message)
      break
  }
}

// 尝试根据路由参数自动加入房间
const tryAutoJoinRoom = () => {
  // 已经在房间内则不再处理
  if (inRoom.value) return

  // 1. 优先根据roomId加入
  if (routeParams.value.roomId && /^\d{4}$/.test(routeParams.value.roomId)) {
    const targetRoom = roomList.value.find(room => room.id === routeParams.value.roomId)
    if (targetRoom) {
      joinSelectedRoom(routeParams.value.roomId)
      return
    } else {
      wsStatus.value = `未找到房间号为 ${routeParams.value.roomId} 的房间`
    }
  }

  // 2. 根据roomName加入
  if (routeParams.value.roomName) {
    const targetRoom = roomList.value.find(room => room.name && room.name.includes(routeParams.value.roomName))
    if (targetRoom) {
      joinSelectedRoom(targetRoom.id)
      return
    } else {
      wsStatus.value = `未找到名称包含 ${routeParams.value.roomName} 的房间`
    }
  }
}

// 转发音视频数据到服务器
const forwardToServer = data => {
  if (!ws.value || ws.value.readyState !== WebSocket.OPEN || !inRoom.value) return

  if (data instanceof ArrayBuffer) {
    ws.value.send(data)
  } else {
    sendWsMessage({
      ...data,
      roomId: currentRoom.value.id
    })
  }
}

// 发送聊天消息
const sendChatMsg = () => {
  if (!msgContent.value.trim() || !inRoom.value) return

  sendWsMessage({
    type: 'chatMessage',
    data: {
      roomId: currentRoom.value.id,
      senderName: userName.value,
      content: msgContent.value,
      time: Date.now()
    }
  })

  msgContent.value = ''
}

/* -------------------------- 辅助函数 -------------------------- */
const formatRoomId = val => {
  const numericVal = val.replace(/\D/g, '')
  roomId.value = numericVal.slice(0, 4)
}

const addSystemMsg = content => {
  messages.value.push({
    senderId: 'system',
    senderName: '系统',
    content,
    time: Date.now()
  })
  scrollToBottom()
}

const scrollToBottom = () => {
  nextTick(() => {
    const msgList = document.querySelector('.message-list')
    if (msgList) {
      msgList.scrollTop = msgList.scrollHeight
    }
  })
}

const formatTime = timestamp => {
  const date = new Date(timestamp)
  return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
}

/* -------------------------- 生命周期 -------------------------- */
onMounted(() => {
  // 1. 提前获取路由参数
  routeParams.value = getUrlParams()

  // 2. 初始化WebSocket连接
  initWebSocket()
})

onBeforeUnmount(() => {
  if (inRoom.value) {
    leaveRoom()
  }

  if (ws.value) {
    ws.value.close(1000, '页面关闭')
    ws.value = null
  }
})
</script>

<style scoped>
.room-entry {
  max-width: 800px;
  margin: 30px auto;
}

.room-form {
  background: #f5f7fa;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 30px;
}

.form-item {
  margin-bottom: 15px;
}

.form-buttons {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.ws-status {
  color: #666;
  font-size: 14px;
  padding: 8px;
  background: #e9f7fe;
  border-radius: 4px;
}

/* 房间列表样式 */
.room-list {
  border: 1px solid #eee;
  border-radius: 8px;
  overflow: hidden;
}

.room-list-header {
  display: flex;
  background: #f0f2f5;
  padding: 12px 15px;
  font-weight: bold;
}

.room-list-item {
  display: flex;
  padding: 12px 15px;
  border-top: 1px solid #eee;
  transition: background 0.2s;
}

.room-list-item:hover {
  background: #f9f9f9;
}

.room-list-col {
  flex: 1;
}

.empty-room {
  text-align: center;
  padding: 30px;
  color: #999;
}

/* 聊天室样式 */
.room-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  border-bottom: 1px solid #eee;
  margin-bottom: 20px;
}

.room-info {
  font-size: 14px;
  color: #333;
  margin-right: 15px;
  font-weight: 500;
}

.user-info {
  font-size: 14px;
  color: #666;
}

.room-content {
  display: flex;
  height: calc(100vh - 220px);
  gap: 20px;
  padding: 0 20px;
}

.video-area {
  flex: 1;
  min-width: 600px;
  background: #f5f5f5;
  border-radius: 8px;
  overflow: hidden;
}

.message-area {
  flex: 0 0 400px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.message-list {
  flex: 1;
  overflow-y: auto;
  border: 1px solid #eee;
  border-radius: 4px;
  padding: 10px;
  height: 0; /* 为了让flex正确工作 */
}

.message-input {
  display: flex;
  gap: 10px;
}

.self-msg,
.other-msg {
  margin: 5px 0;
  padding: 8px 12px;
  border-radius: 6px;
  max-width: 80%;
}

.self-msg {
  background: #e3f2fd;
  margin-left: auto;
  text-align: right;
}

.other-msg {
  background: #f5f5f5;
}

.sender {
  font-weight: bold;
  margin-right: 5px;
}

.time {
  font-size: 12px;
  color: #666;
  margin-left: 10px;
}

/* 手机端适配媒体查询 */
@media (max-width: 768px) {
  .room-entry,
  .chat-room {
    padding: 10px;
    margin: 0;
  }

  .form-buttons {
    flex-direction: column;
  }

  .form-item {
    margin-bottom: 10px;
  }

  .room-list-header,
  .room-list-item {
    font-size: 14px;
  }

  .room-list-col {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .room-list-col:last-child {
    flex: 0 0 60px;
  }

  .room-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 10px;
  }

  .room-content {
    flex-direction: column;
    height: auto;
    min-height: calc(100vh - 220px);
    padding: 0 10px;
  }

  .video-area {
    flex: none;
    min-width: 0;
    width: 100%;
    height: 480px;
  }

  .message-area {
    flex: none;
    width: 100%;
    max-width: none;
    height: 100px;
  }

  .self-msg,
  .other-msg {
    max-width: 90%;
  }

  .sender {
    display: block;
    margin-bottom: 5px;
  }

  .time {
    display: block;
    margin-left: 0;
    margin-top: 5px;
  }

  .form-buttons button {
    width: 100%;
  }

  .room-list-item {
    flex-wrap: wrap;
  }
}

/* 平板设备适配 */
@media (min-width: 769px) and (max-width: 1024px) {
  .room-content {
    flex-direction: column;
  }

  .video-area {
    min-width: 0;
    width: 100%;
    height: 400px;
  }

  .message-area {
    width: 100%;
    max-width: none;
    height: 350px;
  }
}
</style>
